use std::fmt;

/// Pipit 自定义错误类型枚举
#[derive(Debug)]
pub enum PipitError {
    /// IO 错误
    IoError(std::io::Error),
    /// 编译错误
    CompileError(String),
    /// 语法错误
    SyntaxError(String),
    /// 运行时错误
    RuntimeError(String),
    /// 模块加载错误
    ModuleError(String),
    /// 类型错误
    TypeError(String),
    /// 值错误
    ValueError(String),
    /// 索引错误
    IndexError(String),
    /// 除零错误
    DivisionByZeroError(String),
    /// 文件未找到错误
    FileNotFoundError(String),
    /// 权限错误
    PermissionError(String),
    /// 内存不足错误
    OutOfMemoryError(String),
    /// 栈溢出错误
    StackOverflowError(String),
    /// 未实现错误
    NotImplementedError(String),
    /// JIT编译错误
    JitError(String),
}

impl fmt::Display for PipitError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            PipitError::IoError(err) => write!(f, "IO Error: {}", err),
            PipitError::CompileError(msg) => write!(f, "Compile Error: {}", msg),
            PipitError::SyntaxError(msg) => write!(f, "Syntax Error: {}", msg),
            PipitError::RuntimeError(msg) => write!(f, "Runtime Error: {}", msg),
            PipitError::ModuleError(msg) => write!(f, "Module Error: {}", msg),
            PipitError::TypeError(msg) => write!(f, "Type Error: {}", msg),
            PipitError::ValueError(msg) => write!(f, "Value Error: {}", msg),
            PipitError::IndexError(msg) => write!(f, "Index Error: {}", msg),
            PipitError::DivisionByZeroError(msg) => write!(f, "Division By Zero Error: {}", msg),
            PipitError::FileNotFoundError(msg) => write!(f, "File Not Found Error: {}", msg),
            PipitError::PermissionError(msg) => write!(f, "Permission Error: {}", msg),
            PipitError::OutOfMemoryError(msg) => write!(f, "Out Of Memory Error: {}", msg),
            PipitError::StackOverflowError(msg) => write!(f, "Stack Overflow Error: {}", msg),
            PipitError::NotImplementedError(msg) => write!(f, "Not Implemented Error: {}", msg),
            PipitError::JitError(msg) => write!(f, "JIT Error: {}", msg),
        }
    }
}

impl std::error::Error for PipitError {}

impl From<std::io::Error> for PipitError {
    fn from(error: std::io::Error) -> Self {
        PipitError::IoError(error)
    }
}

/// Result类型别名，方便使用
pub type Result<T> = std::result::Result<T, PipitError>;